package com.me.launcher.adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.me.launcher.R;
import com.me.launcher.bean.AppBean;
import com.me.launcher.tools.LogUtil;
import com.me.launcher.tools.ScreenUtils;
import com.me.launcher.tools.Tools;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.me.launcher.activity.WorkSpaceFragment.iconSize;

/**
 * @author hejiangwei
 * @date 2018/3/28
 * 工作区的网格适配器
 */

public class GridViewAdapter extends BaseAdapter {
    private static final String TAG = "GridViewAdapter";
    int screenSize;
    SetLastAppListener mSetLastAppListener;
    /**
     * @mDragBean 从bottom 热键位置拖拽过来的对象
     * @mRemoveBean 从bottom 热键位置拖拽过来的对象
     */
    private AppBean mDragBean, mRemoveBean;
    private LayoutInflater minflater;
    private Context mcontext;
    private List<AppBean> mapps;
    private int hidePosition = AdapterView.INVALID_POSITION;

    private int mdragIndex;
    private AppBean mAppDrag;
    private boolean mbSetEmpty = false;

    /**
     * 从bottom区域拖拽来的app是否落位
     */
    private boolean mbDragSetApp = false;

    public GridViewAdapter(Context mcontext, List<AppBean> mapps, int screenSize, SetLastAppListener mSetLastAppListener) {
        this.mcontext = mcontext;
        this.mapps = mapps;
        this.screenSize = screenSize;
        this.mSetLastAppListener = mSetLastAppListener;
        minflater = LayoutInflater.from(mcontext);
        iconSize = mcontext.getResources().getDimensionPixelSize(R.dimen.x30);
    }

    public List<AppBean> getMapps() {
        if (mapps == null) {
            return new ArrayList<>();
        }
        return mapps;
    }

    public boolean isMbSetEmpty() {
        return mbSetEmpty;
    }

    public void setMbSetEmpty(boolean mbSetEmpty) {
        this.mbSetEmpty = mbSetEmpty;
    }

    public int getHidePosition() {
        return hidePosition;
    }

    public void setHidePosition(int hidePosition) {
        this.hidePosition = hidePosition;
    }

    public AppBean getDragBean() {
        return mDragBean;
    }

    public void setDragBean(AppBean dragBean) {
        mDragBean = dragBean;

    }

    public AppBean getAppDrag() {
        return mAppDrag;
    }

    public int getDragIndex() {
        return mdragIndex;
    }

    public void setMdragIndex(int mdragIndex) {
        this.mdragIndex = mdragIndex;
    }

    public boolean isMbDragSetApp() {
        return mbDragSetApp;
    }

    public void setMbDragSetApp(boolean mbDragSetApp) {
        this.mbDragSetApp = mbDragSetApp;
    }

    @Override
    public int getCount() {
        return mapps.size();
    }

    @Override
    public AppBean getItem(int i) {
        return mapps.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = minflater.inflate(R.layout.layout_item, parent, false);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        //如果没有app的话，不显示
        if (mapps.get(i) == null || mapps.get(i).getActivityInfo() == null) {
            holder.mImageView.setImageDrawable(null);

        } else {
            if ((i == hidePosition)) {
                //如果是隐藏app的话，显示阴影轮廓
                holder.mImageView.setImageBitmap(createDragOutline(Tools.drawableToBitmap(mapps.get(i).getActivityInfo().loadIcon(mcontext.getPackageManager()), 1.2f), 2, iconSize, iconSize, true));
            } else {

                holder.mImageView.setImageDrawable(mapps.get(i).getActivityInfo().loadIcon(mcontext.getPackageManager()));
            }
        }
        holder.mTextView.setText(mapps.get(i) == null ? "" : mapps.get(i).getStrName());

        holder.mTextView.setVisibility((i == hidePosition) ? View.INVISIBLE : View.VISIBLE);

        return convertView;
    }

    private Bitmap createDragOutline(Bitmap orig, int padding, int w, int h,
                                     boolean clipAlpha) {
        Canvas mCanvas = new Canvas();
        final int outlineColor = mcontext.getResources().getColor(R.color.dragView_color);
        final Bitmap b = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
        mCanvas.setBitmap(b);

        Rect src = new Rect(0, 0, orig.getWidth(), orig.getHeight());
        float scaleFactor = Math.min((w - padding) / (float) orig.getWidth(),
                (h - padding) / (float) orig.getHeight());
        int scaledWidth = (int) (scaleFactor * orig.getWidth());
        int scaledHeight = (int) (scaleFactor * orig.getHeight());
        Rect dst = new Rect(0, 0, scaledWidth, scaledHeight);

        // center the image
        dst.offset((w - scaledWidth) / 2, (h - scaledHeight) / 2);

        mCanvas.drawBitmap(orig, src, dst, null);
        applyExpensiveOutlineWithBlur(b, mCanvas, outlineColor, outlineColor,
                clipAlpha);
        mCanvas.setBitmap(null);

        return b;
    }

    void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas, int color,
                                       int outlineColor, boolean clipAlpha) {

        // We start by removing most of the alpha channel so as to ignore shadows, and
        // other types of partial transparency when defining the shape of the object
        if (clipAlpha) {
            int[] srcBuffer = new int[srcDst.getWidth() * srcDst.getHeight()];
            srcDst.getPixels(srcBuffer,
                    0, srcDst.getWidth(), 0, 0, srcDst.getWidth(), srcDst.getHeight());
            for (int i = 0; i < srcBuffer.length; i++) {
                final int alpha = srcBuffer[i] >>> 24;
                if (alpha < 188) {
                    srcBuffer[i] = 0;
                }
            }
            srcDst.setPixels(srcBuffer,
                    0, srcDst.getWidth(), 0, 0, srcDst.getWidth(), srcDst.getHeight());
        }
        Bitmap glowShape = srcDst.extractAlpha();

        // calculate the outer blur first
        Paint mBlurPaint = new Paint();
        BlurMaskFilter mMediumOuterBlurMaskFilter = new BlurMaskFilter(ScreenUtils.getInstance().dp2px(2), BlurMaskFilter.Blur.OUTER);
        mBlurPaint.setMaskFilter(mMediumOuterBlurMaskFilter);
        int[] outerBlurOffset = new int[2];
        Bitmap thickOuterBlur = glowShape.extractAlpha(mBlurPaint, outerBlurOffset);

        BlurMaskFilter mThinOuterBlurMaskFilter = new BlurMaskFilter(
                ScreenUtils.getInstance().dp2px(1), BlurMaskFilter.Blur.OUTER);

        mBlurPaint.setMaskFilter(mThinOuterBlurMaskFilter);
        int[] brightOutlineOffset = new int[2];
        Bitmap brightOutline = glowShape.extractAlpha(mBlurPaint, brightOutlineOffset);
        // calculate the inner blur
        srcDstCanvas.setBitmap(glowShape);
        srcDstCanvas.drawColor(0xFF000000, PorterDuff.Mode.SRC_OUT);
        mBlurPaint.setMaskFilter(mThinOuterBlurMaskFilter);
        int[] thickInnerBlurOffset = new int[2];
        Bitmap thickInnerBlur = glowShape.extractAlpha(mBlurPaint, thickInnerBlurOffset);

        Paint mErasePaint = new Paint();
        mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        mErasePaint.setFilterBitmap(true);
        mErasePaint.setAntiAlias(true);
        // mask out the inner blur
        srcDstCanvas.setBitmap(thickInnerBlur);
        srcDstCanvas.drawBitmap(glowShape, -thickInnerBlurOffset[0],
                -thickInnerBlurOffset[1], mErasePaint);
        srcDstCanvas.drawRect(0, 0, -thickInnerBlurOffset[0], thickInnerBlur.getHeight(),
                mErasePaint);
        srcDstCanvas.drawRect(0, 0, thickInnerBlur.getWidth(), -thickInnerBlurOffset[1],
                mErasePaint);
        Paint mDrawPaint = new Paint();
        mDrawPaint.setFilterBitmap(true);
        mDrawPaint.setAntiAlias(true);


        // draw the inner and outer blur
        srcDstCanvas.setBitmap(srcDst);
        srcDstCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
        mDrawPaint.setColor(color);
        srcDstCanvas.drawBitmap(thickInnerBlur, thickInnerBlurOffset[0], thickInnerBlurOffset[1],
                mDrawPaint);
        srcDstCanvas.drawBitmap(thickOuterBlur, outerBlurOffset[0], outerBlurOffset[1],
                mDrawPaint);

        // draw the bright outline
        mDrawPaint.setColor(outlineColor);
        srcDstCanvas.drawBitmap(brightOutline, brightOutlineOffset[0], brightOutlineOffset[1],
                mDrawPaint);

        // cleanup
        srcDstCanvas.setBitmap(null);
        brightOutline.recycle();
        thickOuterBlur.recycle();
        thickInnerBlur.recycle();
        glowShape.recycle();
    }

    public void hideView(int pos) {
        hidePosition = pos;
        mdragIndex = pos;
        mAppDrag = getItem(mdragIndex);
        notifyDataSetChanged();
    }

    /**
     * 拖拽走之后设置空位
     */
    public void setEmptyView() {
        mbSetEmpty = true;
        if (mdragIndex >= 0) {
            mapps.set(mdragIndex, new AppBean.Builder().build());
            mSetLastAppListener.onChangeApps();

        }
        notifyDataSetChanged();
    }

    /**
     * 还原刚刚被拖拽走的app
     */
    public void setRemoveDrag() {
        if (mdragIndex >= 0) {
            mapps.set(mdragIndex, mAppDrag == null ? (new AppBean.Builder().build()) : mAppDrag);
            hidePosition = mdragIndex;
            mSetLastAppListener.onChangeApps();
            notifyDataSetChanged();

        }
    }

    public void removeView(int pos) {
        mapps.remove(pos);
        notifyDataSetChanged();
    }

    public void setDragView() {
        if (hidePosition >= 0) {
            mbDragSetApp = false;
            mapps.set(hidePosition, new AppBean.Builder().build());
            mSetLastAppListener.onChangeApps();
            showHideView();
        }
    }

    public void showHideView() {
        hidePosition = AdapterView.INVALID_POSITION;
        notifyDataSetChanged();
    }

    /**
     * 更新拖动时的gridView中的app位置
     *
     * @param draggedPos
     * @param destPos
     */
    public void swapView(int draggedPos, int destPos) {
        mdragIndex = destPos;
                    LogUtil.e(TAG, "swapView===mdragIndex=="+draggedPos +"="+destPos);
        if (draggedPos == -1) {
            //代表是从其他控件拖进来的

            mbDragSetApp = true;
            if (getItem(destPos).getActivityInfo() == null) {
                //要占位的是空

                mapps.set(destPos, mDragBean == null ? (new AppBean.Builder().build()) : mDragBean);
            } else {
                if (getEmptyIndex(destPos) < 0) {
                    //全屏无空位
                    mapps.add(destPos, mDragBean == null ? (new AppBean.Builder().build()) : mDragBean);
                    mRemoveBean = mapps.get(mapps.size() - 1);

                    LogUtil.e(TAG, "swapView==="+destPos+"=="+mapps.get(destPos).getStrName() );
                    mSetLastAppListener.setLastApp(mRemoveBean);
                    mapps.remove(mapps.size() - 1);
                } else {
                    //全屏有空位
                    Collections.swap(mapps, getEmptyIndex(destPos), destPos);
                    mapps.set(destPos, mDragBean == null ? (new AppBean.Builder().build()) : mDragBean);

                }
            }
//            if (getScreenAppNum() > screenSize) {
//                mRemoveBean = mapps.get(mapps.size() - 1);
//                mSetLastAppListener.setLastApp(mRemoveBean);
//                mapps.remove(mapps.size() - 1);
//
//            } else {
//                //如果有空位
//
//                mapps.remove(getEmptyIndex(destPos));
//            }
        } else {

            Collections.swap(mapps, draggedPos, destPos);
        }
        mSetLastAppListener.onChangeApps();

        //从前向后拖动，其他item依次前移
//        if (draggedPos < destPos) {
//            mapps.add(destPos + 1, getItem(draggedPos));
//            mapps.remove(draggedPos);
//        }
        //从后向前拖动，其他item依次后移
//        else if (draggedPos > destPos) {
//            mapps.add(destPos, getItem(draggedPos));
//            mapps.remove(draggedPos + 1);
//        }
        hidePosition = destPos;
        notifyDataSetChanged();
    }

    /**
     * 获取空位的索引
     * @param index
     * @return
     */
    private int getEmptyIndex(int index) {
        int def = -1;
        for (int i = index; i < mapps.size(); i++) {
            if (mapps.get(i).getActivityInfo() == null) {
                def = i;
                return def;
            }
        }
        for (int i = 0; i < index; i++) {
            if (mapps.get(i).getActivityInfo() == null) {
                def = i;
                return def;
            }
        }
        return def;

    }

    /**
     * 获取当前页面的app数量
     * @return
     */
    private int getScreenAppNum() {
        int size = 0;
        for (AppBean appBean : mapps) {
            if (appBean != null && appBean.getActivityInfo() != null) {
                size += 1;

            }
        }
        return size;

    }

    public interface SetLastAppListener {
        void setLastApp(AppBean app);

        void onChangeApps();
    }

    public class ViewHolder {
        public ImageView mImageView;
        public TextView mTextView;

        public ViewHolder(View convertView) {
            super();

            mImageView = convertView.findViewById(R.id.img_icon);
            mTextView = convertView.findViewById(R.id.text_name);
//            float raio = (ScreenUtils.getInstance().getScreenW() - ScreenUtils.getInstance().dp2px(200)) * 1f / ScreenUtils.getInstance().dp2px(200);
            if (iconSize!=mcontext.getResources().getDimensionPixelOffset(R.dimen.x35)) {
                mImageView.getLayoutParams().height = iconSize;
                mImageView.getLayoutParams().width = iconSize;
                mImageView.requestLayout();
            }
        }
    }
}
